﻿Imports System.Windows.Forms
Imports System.Text
Imports System.IO
Imports System.Net


Public Class Export_Dgv_to_dgv_to_xml

    Private _Export_OK As Boolean = False
    ReadOnly Property Export_OK() As Boolean
        Get
            Return _Export_OK
        End Get
    End Property


    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="dgv"></param>
    ''' <param name="FileName"></param>
    ''' <param name="info"></param>
    ''' <remarks></remarks>
    Sub New(dgv As DataGridView, FileName As String, info As String)

        If dgv IsNot Nothing Then
            ExportDataGrid_To_XML_File(dgv, info, FileName)
        Else

            If is_Language_German_Active() Then
                MessageBox.Show("Fehler: DataGrid ist leer!", "Export in eine XML-Datei", MessageBoxButtons.OK)
            Else
                MessageBox.Show("Error: DataGrid is empty!", "Export as XML-File", MessageBoxButtons.OK)
            End If

            _Export_OK = False
        End If
    End Sub


    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="dgv"></param>
    ''' <param name="info"></param>
    ''' <param name="XmlFileName"></param>
    ''' <remarks></remarks>
    Private Sub ExportDataGrid_To_XML_File(dgv As DataGridView, info As String, XmlFileName As String)
        Dim icolum As Integer
        Dim iRow As Integer
        Dim XMLFileLine As String = String.Empty

        Try
            dgv.EndEdit()
            dgv.Update()

            ' create File
            Dim fs As FileStream = New FileStream(XmlFileName, FileMode.Create, FileAccess.Write)

            ' open StreamWriter
            Using sw As StreamWriter = New StreamWriter(fs, System.Text.Encoding.UTF8)

                sw.WriteLine("<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>")

                If info.Trim.Length > 0 Then
                    sw.WriteLine("<!-- " & info.ToString() & " -->")
                End If


                sw.WriteLine("<NewDataset>")
                For iRow = 0 To dgv.Rows.Count - 1

                    If Not dgv.Rows(iRow).IsNewRow Then
                        sw.WriteLine(ThreeSpaceChar(1) + "<" + Path.GetFileNameWithoutExtension(XmlFileName) + ">")
                        For icolum = 0 To dgv.Rows(iRow).Cells.Count - 1

                            If dgv.Rows(iRow).Cells.Item(icolum).Value IsNot Nothing Then

                                If dgv.Rows(iRow).Cells.Item(icolum).Value.ToString().Length > 0 Then

                                    XMLFileLine = ThreeSpaceChar(2)
                                    XMLFileLine = XMLFileLine + "<" + XML_Fake_ElementName(dgv.Columns.Item(icolum).HeaderText().Trim) + ">"
                                    XMLFileLine = XMLFileLine + dgv.Rows(iRow).Cells.Item(icolum).Value.ToString()
                                    XMLFileLine = XMLFileLine + "</" + XML_Fake_ElementName(dgv.Columns.Item(icolum).HeaderText().Trim) + ">"

                                    sw.WriteLine(XMLFileLine)

                                Else
                                    sw.WriteLine(ThreeSpaceChar(2) + "<" + XML_Fake_ElementName(dgv.Columns.Item(icolum).HeaderText().Trim) + " />")
                                End If
                            Else
                                sw.WriteLine(ThreeSpaceChar(2) + "<" + XML_Fake_ElementName(dgv.Columns.Item(icolum).HeaderText().Trim) + " />")
                            End If

                        Next
                        sw.WriteLine(ThreeSpaceChar(1) + "</" + Path.GetFileNameWithoutExtension(XmlFileName).Trim + ">")
                    End If

                Next

                sw.WriteLine("</NewDataset>")

                ' close StreamWriter and File
            End Using

            fs.Close()
            _Export_OK = True

            Exit Sub

        Catch ex As Exception

            Dim dgv_CellInfo As String
            dgv_CellInfo = "Table: " & Chr(13) & "Row:<" + iRow.ToString().Trim() + "> Col:<" + icolum.ToString().Trim() + ">"
            MessageBox.Show(dgv_CellInfo + Chr(13) + ex.Message(), "XML-Writer-Info - Exception", MessageBoxButtons.OK)
        End Try
    End Sub

    Private Function ThreeSpaceChar(count As Integer) As String
        Dim i As Integer
        ThreeSpaceChar = ""
        For i = 1 To count
            ThreeSpaceChar = ThreeSpaceChar + "   "
        Next
    End Function

    Private Function XML_Fake_ElementName(ElementName As String) As String
        Dim i As Integer

        XML_Fake_ElementName = String.Empty
        ElementName = ElementName.Trim

        If InStr(ElementName, " ") > 0 Then
            For i = 1 To Len(ElementName)

                If Mid(ElementName, i, 1) <> " " Then
                    XML_Fake_ElementName = XML_Fake_ElementName + Mid(ElementName, i, 1)
                Else
                    XML_Fake_ElementName = XML_Fake_ElementName + "_x0020_"
                End If

            Next
        Else
            XML_Fake_ElementName = ElementName
        End If

        XML_Fake_ElementName = encoding_to_UTF8(XML_Fake_ElementName)
    End Function

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="str"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function encoding_to_UTF8(ByVal str As String) As String
        Try

            Dim encodedString() As Byte
            Dim utf8_Encoding As New System.Text.UTF8Encoding(True)

            encodedString = utf8_Encoding.GetBytes(str)
            Return utf8_Encoding.GetString(encodedString)
        Catch ex As Exception
            Return str
        End Try
    End Function


    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="text"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function HtmlEncode(text As String) As String

        Dim chars As Char() = WebUtility.HtmlEncode(text).ToCharArray()

        Dim result As New StringBuilder(text.Length + CInt(text.Length * 0.1))

        For Each c As Char In chars
            Dim value As Integer = Convert.ToInt32(c)
            If value > 127 Then
                result.AppendFormat("&#{0};", value)
            Else
                result.Append(c)
            End If
        Next

        Return result.ToString()
    End Function

    ''' <summary>
    ''' determine if in Windows as a language German active 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function is_Language_German_Active() As Boolean
        Try
            Dim cultureName As String = Threading.Thread.CurrentThread.CurrentCulture.Name
            If cultureName.Substring(0, 2) = "de" Then
                is_Language_German_Active = True
            Else
                is_Language_German_Active = False
            End If
        Catch
            is_Language_German_Active = False
        End Try
    End Function
End Class
